package com.jhf.youke.core.utils;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * @author RHJ
 */
public class RsaUtils {

	private static final String ALGOGRITHM = "RSA";

	/** RSA最大加密明文大小 **/
	private static final int MAX_ENCRYPT_BLOCK = 117;

	/** RSA最大解密密文大小 **/
	private static final int MAX_DECRYPT_BLOCK = 128;

	/**
	 * 解密方法
	 * 参数： 解密内容为普通Strng ,私钥 返回一个字符串
	 * */
	public static String decrypt(String content, PrivateKey privateKey)throws Exception {
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		byte[] cipherText = Base64.decodeBase64(content);
		// 解密时超过字节报错。为此采用分段解密的办法来解密
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < cipherText.length; i += MAX_DECRYPT_BLOCK) {
			byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(cipherText, i, i + MAX_DECRYPT_BLOCK));
			sb.append(new String(doFinal));
		}
		return sb.toString();
	}

	/**
	 * 加密方法
	 * 参数： 加密内容为普通Strng ,公钥 返回一个字符串
	 * */
	public static String encryption(String content, PublicKey publicKey) throws Exception {
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		byte[] data = content.getBytes("UTF-8");
		// 加密时超过117字节就报错。为此采用分段加密的办法来加密
		byte[] enBytes = null;
		for (int i = 0; i < data.length; i += MAX_ENCRYPT_BLOCK) {
			// 注意要使用2的倍数，否则会出现加密后的内容再解密时为乱码
			byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + MAX_ENCRYPT_BLOCK));
			enBytes = ArrayUtils.addAll(enBytes, doFinal);
		}
		return new Base64().encodeToString(enBytes);
	}

	/**
	 * 将字符转为私钥
	 * */
	public static PrivateKey getPrivateKey(String priKey) {
		PrivateKey privateKey = null;

		PKCS8EncodedKeySpec priPkcs8;
		try {
			priPkcs8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(priKey));
			KeyFactory keyf = KeyFactory.getInstance("RSA");
			privateKey = keyf.generatePrivate(priPkcs8);
		} catch (NoSuchAlgorithmException e) {
			e.getMessage();
		} catch (InvalidKeySpecException e) {
			e.getMessage();
		}
		return privateKey;
	}


	/**
	 * 将字符转为公钥
	 * */
	public static PublicKey getPublicKey(String pubkey) {
		PublicKey publicKey = null;
		X509EncodedKeySpec pubX509;
		try {
			pubX509 = new X509EncodedKeySpec(Base64.decodeBase64(pubkey));
			KeyFactory keyf = KeyFactory.getInstance("RSA");
			publicKey = keyf.generatePublic(pubX509);
		} catch (NoSuchAlgorithmException e) {
			e.getMessage();
		} catch (InvalidKeySpecException e) {
			e.getMessage();
		}
		return publicKey;
	}

}
